
/*********************************************************/
/*     dlg_main.cpp      CHAOXED's Main Dialog (Win32)   */
/*                       By: Josh Fiorio                 */
/*********************************************************/

#include "dlg_main.h"

//Global variables
extern FrameBuffer fbuf;
extern FrameBuffer showbuf;
extern FrameBuffer prevbuf;
extern int mousex, mousey, mousedown;

extern FILE *ROM;
extern int rom_pos;
extern bool rom_open;

extern pointer pointers[17];
extern long pdata[17];

extern palette palettes[17];
extern long paldata[17];
extern int curCol;

extern art curArt;
extern int artMag;

extern long pcolor;
extern long defgrcol;

//Main Dialog Variables
int pl1Sel=0;
int pl2Sel=0;
char status[100]="Ready";
char status2[100]="0,0";
bool transActive=false;
bool grid=true;

BOOL CALLBACK MAIN_DLG_Func(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	
    switch (message)	
	{
		case WM_INITDIALOG:
		{
			//SET ICONS
			SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MAIN_ICON)));
			SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MAIN_ICON)));;

			//Init buffers to handles we paint to
			fbuf.Init    (245,206,3);
			showbuf.Init (245,206);
			prevbuf.Init ( 61, 85);

			break;
        }   //end case

		case WM_CLOSE:
        {
			DestroyWindow(hwnd);
			break;
        }   //end case

		case WM_DESTROY:
        {
            if (rom_open)
            {
                unsigned short checkSum = CalcCheckSum();
                unsigned short romSum = GetRomSum();
                unsigned long checkSize = lof()-1;
                unsigned long romSize = 0;
                rom_pos = 0x01a4; fseek(ROM, rom_pos, 0); fread(&romSize, 4, 1, ROM); 
                romSize = jntohl(romSize);
                 
                if (checkSum != romSum || romSize != checkSize)
                {
                    char *finalstr = (char*)malloc(512);
                    sprintf(finalstr, "The checksum within the ROM is not identical to the calculated checksum of the ROM\n\n   Checksum in ROM:\t%i\n   Calculated checksum:\t%i\n   ROM Size in ROM:\t\t%i\n   Calculated ROM Size:\t%i\n\nWould you like to fix this ROM's checksum?", (int)romSum, (int)checkSum, (int)romSize, (int)checkSize);
                    
                    if (MessageBox(NULL, finalstr, "Chaotix art Editor", MB_ICONINFORMATION | MB_YESNO) == IDYES)
                    {
                       FixRomSum(checkSum);
                       romSum = GetRomSum();
                       
                       if (romSum != checkSum)
                          MessageBox(NULL, "The checksum was not fixed...", "Chaotix art Editor", MB_ICONINFORMATION);
                       //end if
                       
                       checkSize = jhtonl(checkSize);
                       rom_pos = 0x01a4; fseek(ROM, rom_pos, 0); fwrite(&checkSize, 4, 1, ROM);
                    }  //end if
                }   //end if
            }   //end if
                 
    		PostQuitMessage(0);
    		break;
        }   //end case
        
 		case WM_PAINT:
        {	
                //For device context for main_dlg
                HDC hdc;
                PAINTSTRUCT ps;
            
                hdc = BeginPaint(hwnd, &ps);

                	//Draw status-bar
                	DrawMainStatusBar(hwnd, hdc);
    
                    //Convert and draw framebuffers                    
                	CopyBuf(fbuf, showbuf);
                	if (grid) { GridToBuf(showbuf,defgrcol); }
                    MagBuf(fbuf, artMag, prevbuf, 1);
                    BlitBuf(hwnd, hdc, showbuf, ART_EDIT_BOX);
                    BlitBuf(hwnd, hdc, prevbuf, ART_PREV_BOX);
                    
                    //Draw colorboxes
                    PaintColorBoxes(hwnd, hdc);
                    
                EndPaint(hwnd, &ps);
            	
				//We need to paint the other portions of the dialog
				return false;

			break;
        }   //end case

		case WM_NOTIFY: 
        case WM_COMMAND: //HIWORD of wparam = action, LOWORD of wparam = control id, lparam = control handle
		{
        	//----check menu items----
			switch (LOWORD(wparam))
			{
    			case ID_FILE_EXIT:
    			{
                	DestroyWindow(hwnd);
    				break;
                }   //end case
                case ID_HELP_ABOUT:
                {
    				//create our dialog and show
    				int about;
    				about = DialogBox(GetModuleHandle(NULL), (LPCTSTR) MAKEINTRESOURCE(ABOUT_DLG), 
    					hwnd, ABOUT_DLG_Func);
    				break;
                }   //end case
                case ID_OPENCHAOTIXROM:
                {
                    //Try to get pointer to filename with an openfile box
                	char *pfilename;
                	if (!(pfilename = OpenFileBox(
                		"Load a Chaotix Rom",
                		"Chaotix Roms (binary)\0*.bin\0Chaotix Roms (smd)\0*.smd\0Chaotix Roms (32x)\0*.32x\0All Files\0*.*\0"
                		))) { break; }
                
                	//Copy pointed data into an array
                	char filename[MAX_PATH];
                	int len=0;
                	while (true)
                	{
                		filename[len] = *(pfilename+len);
                		if (*(filename + len) == 0)
                			break;
                		len++;
                	}	//end copying
                	
                	//Now try and open the file assigning it to ROM
                	if ((ROM = fopen(filename, "r+b")) == NULL)
                		break;
                	else
                		rom_open = true;
                	//end if
                
                	//Get pointer Data
                	ZeroMemory(&pointers, sizeof(pointers));
                	
                	for (int lp=0; lp < sizeof(pdata)/4; lp++)
                		InitPointer(pointers[lp], pdata[lp]);
                	//end for
                	
               	    //Get palette Data
                	ZeroMemory(&palettes, sizeof(palettes));
                	
                	for (int lp=0; lp < sizeof(paldata)/4; lp++)
                		InitPalette(palettes[lp], paldata[lp]);
                	//end for
                	
                	//Get art Data
                	InitArt(curArt, pointers[0].pointsto[0]);
                    ArtToBuf(curArt, palettes[pl1Sel], fbuf);
                	
                    //Show pointer data in the listboxes
                	UpdatePointers(pointers, hwnd);
                	
                	//Paint dialog
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
       	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
       	            for (int palOn=0; palOn<=16; palOn++)
                    InvalidateDlgItem(hwnd, (int)((COL_BOX1)+(palOn))); 
       	            
                	break;
                }   //end case
    			case ID_VIEW_GRIDLINES:
                {
    				//Toggle grid variable
                    if (grid==false){grid=true;} else{grid=false;}
                    
                	//Paint dialog
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
       	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
       	            
		            break;
    			}   //end case
            }   //end switch

			//from here on don't do anything if rom not open
			if (!rom_open) { return true; }
			
			//----check dialog items----

			//buttons
			if (HIWORD(wparam) == BN_CLICKED)
			{
				if (LOWORD(wparam) == IDC_WT1)
				{
					MessageBox(hwnd, 
					"This is basically just a list of pointers in your chaotix rom, each one standing for art. They each point to more pointers, which are the list of pointers on the right side, that point to each frame of art.",
					"What is this?", MB_ICONINFORMATION);
				}	//end if

				if (LOWORD(wparam) == IDC_WT2)
				{
					MessageBox(hwnd, 
					"This is a list of pointers that point to 1 frame of art. To edit the art, click the pointer that points to it, and use the art editor.",
					"What is this?", MB_ICONINFORMATION);
				}	//end if

				if (LOWORD(wparam) == IDC_SAVE_ART)
				{
					//Declare position
					long pos=0;

					//Retrieve the users choice
					if (MessageBox(hwnd, "Would you like to put this art at the end of the file? (Better)", "Question", MB_YESNO | MB_ICONQUESTION) == IDYES)
						pos=lof();
					else
						pos=InputBox("Enter a position to point pointer to");
					//end if

					//Get art from our buffer
					BufToArt(curArt, palettes[pl1Sel], fbuf);

					//New art, so lets write it to to our position
					WriteArt(curArt, pos);

					//Now we must change the pointer to point to our position
					pointers[pl1Sel].pointsto[pl2Sel]=pos;
					WritePointer(pointers[pl1Sel],pl2Sel);
					
					//Get pointer Data
					UpdatePointers(pointers, hwnd);
				}	//end if

				if (LOWORD(wparam) == IMPORT_BITMAP)
				{
					int bibox=0;
					bibox = DialogBox(GetModuleHandle(NULL), (LPCTSTR) MAKEINTRESOURCE(BI_DLG), 
					hwnd, BI_DLG_Func);
				    
                    //Paint dialog
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
       	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
                    for (int palOn=0; palOn<=16; palOn++)
                            InvalidateDlgItem(hwnd, (int)((COL_BOX1)+(palOn))); 
       	            
				}	//end if

				if (LOWORD(wparam) == EXPORT_BITMAP)
				{
					//Browse for file
					char be_filename[MAX_PATH];
					char *bname;
					if (!(bname = SaveFileBox(
						"Export a Bitmap File",
						"Bitmap Files\0*.bmp\0All Files\0*.*\0",
						"bmp"
						))) { return 0; }

					//Copy pointed data into an array
					int len=0;
					bool done=false;
					while (!done)
					{
						be_filename[len] = *(bname+len);
						if (*(be_filename + len) == 0)
							done=true;
						len++;
					}	//end copying

					BufToBitmap(be_filename, prevbuf);
				}	//end if

				if (LOWORD(wparam) == IMPORT_PIXELS)
				{
					//Browse for file
					char pxe_filename[MAX_PATH];
					char *bname;
					if (!(bname = OpenFileBox(
						"Import an Uncompressed Art File",
						"Uncompressed Art Files\0*.bin\0Uncompressed Art Files\0*.dat\0All Files\0*.*\0"
						))) { return 0; }

					//Copy pointed data into an array
					int len=0;
					bool done=false;
					while (!done)
					{
						pxe_filename[len] = *(bname+len);
						if (*(pxe_filename + len) == 0)
							done=true;
						len++;
					}	//end copying

                    int wid = InputBox("Enter width (number of tiles across) to import: ");
                    int hgt = InputBox("Enter height (number of tiles up & down) to import: ");
					UArtToBuf(pxe_filename, wid, hgt, fbuf, palettes[pl1Sel]);
					
				    //Paint dialog
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
       	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
                    for (int palOn=0; palOn<=16; palOn++)
                            InvalidateDlgItem(hwnd, (int)((COL_BOX1)+(palOn))); 
				}	//end if

				if (LOWORD(wparam) == EXPORT_PIXELS)
				{
					//Browse for file
					char pxe_filename[MAX_PATH];
					char *bname;
					if (!(bname = SaveFileBox(
						"Export a Uncompressed Art File",
						"Uncompressed Art Files\0*.bin\0Uncompressed Art Files\0*.dat\0All Files\0*.*\0",
						"bin"
						))) { return 0; }

					//Copy pointed data into an array
					int len=0;
					bool done=false;
					while (!done)
					{
						pxe_filename[len] = *(bname+len);
						if (*(pxe_filename + len) == 0)
							done=true;
						len++;
					}	//end copying

					BufToUArt(pxe_filename, prevbuf, palettes[pl1Sel]);
					PaletteToFile("C:/tst.tpl", palettes[pl1Sel]);
				}	//end if

				if (LOWORD(wparam) == IMPORT_PIXELS_SC)
				{

					char pxe_filename[MAX_PATH];
					char pxe_filename2[MAX_PATH];

					char *bname;
					if (!(bname = OpenFileBox(
						"Choose the .SC file you would like to use to import",
						"SC Files\0*.sc\0All Files\0*.*\0"
						))) { return 0; }

					//Copy pointed data into an array
					int len=0;
					bool done=false;
					while (!done)
					{
						pxe_filename[len] = *(bname+len);
						if (*(pxe_filename + len) == 0)
							done=true;
						len++;
					}	//end copying

					if (!(bname = OpenFileBox(
						"Choose the ROM to import pixel data from",
						"Genesis Roms (binary)\0*.bin\0Genesis Roms (smd)\0*.smd\0Genesis Roms (32x)\0*.32x\0All Files\0*.*\0"
						))) { return 0; }

					//Copy pointed data into an array
					len=0;
					done=false;
					while (!done)
					{
						pxe_filename2[len] = *(bname+len);
						if (*(pxe_filename2 + len) == 0)
							done=true;
						len++;
					}	//end copying

					ROMArtViaSCToBuf(pxe_filename2, pxe_filename, fbuf, palettes[pl1Sel]);
					
       	            //Update boxes
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
       	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
                    for (int palOn=0; palOn<=16; palOn++)
                            InvalidateDlgItem(hwnd, (int)((COL_BOX1)+(palOn))); 
       	            
				}	//end if


				if (LOWORD(wparam) == MAG_ART)
				{
                    //magnify the actual buffer
					if (artMag < 8)
					{
						BufToArt(curArt, palettes[pl1Sel], fbuf);		  //copy what we are going to magnify from our buffer to our current art
						fbuf.Clear();				                      //clear it so we don't display over it
						artMag++;					                      //add to our magnify variable, which the displaying of the art depends on
						ArtToBuf(curArt, palettes[pl1Sel], fbuf);	      //now copy our art back into the buffer, which since now we changed our magnify variable it magnifys
					}	//end if

					//disable/enable menu items
					HMENU theMenu=GetMenu(hwnd);
					if (artMag==1) { EnableMenuItem(theMenu, DEMAG_ART, MF_GRAYED); }
					else if (artMag==2) { EnableMenuItem(theMenu, DEMAG_ART, MF_ENABLED); }
					else if (artMag==7) { EnableMenuItem(theMenu, MAG_ART, MF_ENABLED); }
					else if (artMag==8) { EnableMenuItem(theMenu, MAG_ART, MF_GRAYED); }
					DrawMenuBar(hwnd);
					
       	            //Update display box only
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
				}	//end if

				
				if (LOWORD(wparam) == DEMAG_ART)
				{
                    //magnify the actual buffer
					if (artMag > 1)
					{
						BufToArt(curArt, palettes[pl1Sel], fbuf);		  //copy what we are going to de-magnify from our buffer to our current art
						fbuf.Clear();				                      //clear it so we don't display over it
						artMag--;					                      //subtract from our magnify variable, which the displaying of the art depends on
						ArtToBuf(curArt, palettes[pl1Sel], fbuf);	      //now copy our art back into the buffer, which since now we changed our magnify variable it magnifys
					}	//end if
			
					//disable/enable menu items
					HMENU theMenu=GetMenu(hwnd);
					if (artMag==1) { EnableMenuItem(theMenu, DEMAG_ART, MF_GRAYED); }
					else if (artMag==2) { EnableMenuItem(theMenu, DEMAG_ART, MF_ENABLED); }
					else if (artMag==7) { EnableMenuItem(theMenu, MAG_ART, MF_ENABLED); }
					else if (artMag==8) { EnableMenuItem(theMenu, MAG_ART, MF_GRAYED); }
					DrawMenuBar(hwnd);
					
       	            //Update display box only
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
				}	//end if

				if (LOWORD(wparam) == IDC_TRANS)
				{
					if (transActive==false)
						transActive=true;
					else
						transActive=false;
					//end if
				}	//end if
				
			} //end if

			//listboxes
			if (HIWORD(wparam) == LBN_SELCHANGE)
			{ 
				if (LOWORD(wparam) == PTR_LST1)
				{
					pl1Sel = SendDlgItemMessage(hwnd, PTR_LST1, LB_GETCURSEL, 0, 0);
						if (pl1Sel == -1 || pl1Sel >= 256) { pl1Sel = 0; }
					pl2Sel = 0;

					//Display new pointers according to pointer selected
					UpdatePointers(pointers, hwnd);
                    UpdateWindow(hwnd);
					
					//Load new art according to what pointers selected
					InitArt(curArt, pointers[pl1Sel].pointsto[0]);
                    ArtToBuf(curArt, palettes[pl1Sel], fbuf);

                    //Paint dialog (Update colorboxes w/arts)
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
       	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
                    for (int palOn=0; palOn<=16; palOn++)
                            InvalidateDlgItem(hwnd, (int)((COL_BOX1)+(palOn))); 
                    
				}	//end if

				if (LOWORD(wparam) == PTR_LST2)
				{
					pl2Sel = SendDlgItemMessage(hwnd, PTR_LST2, LB_GETCURSEL, 0, 0);
						if (pl2Sel == -1) { pl2Sel = 0; }

					//Load new art according to what pointers selected
					InitArt(curArt, pointers[pl1Sel].pointsto[pl2Sel]);
                    ArtToBuf(curArt, palettes[pl1Sel], fbuf);

       	            //Update boxes
       	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
       	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
				}	//end if
			}	//end if

			if (HIWORD(wparam) == LBN_DBLCLK)
			{	
				if (LOWORD(wparam) == PTR_LST2)
				{
					//Get where the user wants the new position
					long newPos=InputBox("Enter a new address: ");
					
					if (newPos != -1)
					{
						//Get what is selected
						pl2Sel = SendDlgItemMessage(hwnd, PTR_LST2, LB_GETCURSEL, 0, 0);
						if (pl2Sel == -1) { pl2Sel = 0; }

						//Now we must change the pointer to point to that address
						pointers[pl1Sel].pointsto[pl2Sel]=newPos;
						WritePointer(pointers[pl1Sel],pl2Sel);
						
						//Update new pointers
						UpdatePointers(pointers, hwnd);
					}
					else
						MessageBox(hwnd, "Invalid Address", NULL, MB_ICONWARNING);
					//end if
				}	//end if
			}	//end if
					

			//color boxes
			if (HIWORD(wparam) == STN_CLICKED)
			{
				if (LOWORD(wparam) >= COL_BOX1 && LOWORD(wparam) <= COL_BOX16)
					curCol = LOWORD(wparam) - COL_BOX1;
                InvalidateDlgItem(hwnd, COL_SEL); 
			}	//end if

			if (HIWORD(wparam) == STN_DBLCLK)
			{
				if (LOWORD(wparam) >= COL_BOX1 && LOWORD(wparam) <= COL_BOX16)
				{
					//Define a choosecolor dialog box
					CHOOSECOLOR cc;
					
					COLORREF cColors[16] = {0};
					for (int lp=0; lp<=sizeof(cColors)/4; lp++) 
						cColors[lp]=RGB(255,255,255);
					//end for
					
					cc.lStructSize = sizeof(CHOOSECOLOR);
					cc.hwndOwner = hwnd;
					cc.hInstance = (HWND) GetModuleHandle(NULL);
					cc.rgbResult = c32to256(palettes[pl1Sel].colors[LOWORD(wparam)-COL_BOX1]);
					cc.lpCustColors = cColors;
					cc.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ANYCOLOR;;

					//Show box
					if (ChooseColor(&cc))
					{
						//if color is chosen then modify palettes and display
						palettes[pl1Sel].colors[LOWORD(wparam)-COL_BOX1] = c256to32(cc.rgbResult);

						//check if we want to save palettes
						if (MessageBox(hwnd, "Would you like to save these changes to the ROM?", NULL, MB_YESNO | MB_ICONQUESTION) == IDYES)
							WritePalette(palettes[pl1Sel]);
						//end if
						
						//Paint dialog (PAiNT COlOR BOXES)
           	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
           	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
                        for (int palOn=0; palOn<=16; palOn++)
                            InvalidateDlgItem(hwnd, (int)((COL_BOX1)+(palOn))); 
					}	//end if
				}	//end if
			}	//end if

			//other menu items
			if (LOWORD(wparam) >= ID_SHIFTART_UP && LOWORD(wparam) <= ID_SHIFTART_RIGHT)
			{
				switch (LOWORD(wparam))
				{
				case ID_SHIFTART_UP:
					ShiftBuf(fbuf, 0, -artMag);
					break;
				case ID_SHIFTART_DOWN:
					ShiftBuf(fbuf, 0, artMag);
					break;
				case ID_SHIFTART_LEFT:
					ShiftBuf(fbuf, -artMag, 0);
					break;
				case ID_SHIFTART_RIGHT:
					ShiftBuf(fbuf, artMag, 0);
					break;
				}	//end switch

   	            //Update boxes
   	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
   	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
			}	//end if

			break;
        }   //end case
        
		//--Check if user paints on our static--
		case WM_LBUTTONDOWN:
			mousedown=true;
			SendMessage(hwnd, WM_MOUSEMOVE, 0, 0);
			break;
		case WM_LBUTTONUP:
			mousedown=false;
			break;
		case WM_MOUSEMOVE:
			//from here on don't do anything if rom not open
			if (!rom_open) { return true; }

			//stuff for click our window
			POINT mousepnt;				//point for store mouse pos
			RECT windrect, contrect;	//point for store window & control pos

			//Get poses of stuff
			GetWindowRect(hwnd, &windrect);
			GetWindowRect(GetDlgItem(hwnd, ART_EDIT_BOX), &contrect);
			GetCursorPos(&mousepnt);

			//Do math to figure out relativatey to control
			mousex=(mousepnt.x-contrect.left); /*-2*/
			mousey=(mousepnt.y-contrect.top); /*-2*/
			mousex = mousex - (mousex % (artMag));
			mousey = mousey - (mousey % (artMag));

			//Display mouse position in status bar if mouse is over static
			if (mousex >= 0 && mousey >= 0 && mousex <= ((3735/15)-4) && mousey <= ((3135/15)-3))
            {		
				sprintf(status2, "%i,%i", mousex/artMag, mousey/artMag);
                RECT frect;
                GetClientRect(hwnd, &frect);
                frect.top = frect.bottom - 21;
                InvalidateRect(hwnd, &frect, false);
            }
			else if (strcmp(status2, "") != 0)	
			{
				sprintf(status2, "");
                RECT frect;
                GetClientRect(hwnd, &frect);
                frect.top = frect.bottom - 21;
                InvalidateRect(hwnd, &frect, false);
            }	//end if
            
			//check if we are painting to our static picture
			if (mousedown)
			{
					if (mousex >= 0 && mousey >= 0 && mousex <= ((3735/15)-4) && mousey <= ((3135/15)-3))
					{
						for (int yp=0; yp<artMag; yp++)
						{
							for (int xp=0; xp<artMag; xp++)
							{
								if (!transActive)
									fbuf.SetPixel (((mousex))+xp, ((mousey))+yp, c32to256(palettes[pl1Sel].colors[curCol]));
								else
									fbuf.SetPixel (((mousex))+xp, ((mousey))+yp, c32to256(c256to32(pcolor)));
							}	//end for
						}	//end for
												
						// --- We should only do this part of code when it is completely neccessary
						// --- For example, do this when we want to save what pixels we have in our
						// --- art static control back into the current art. So we would only do this
						// --- when we zoom, because the zoom code zooms what we have of our current art
						// --- and we want to zoom the edited art, not the original.
						//
						//			BufToArt(curArt, fbuf);
						//			ArtToBuf(curArt, fbuf);

           	            //Update boxes
           	            InvalidateDlgItem(hwnd, ART_EDIT_BOX);
           	            InvalidateDlgItem(hwnd, ART_PREV_BOX);
					}
					else
						mousedown = false;
					//end if
			}	//end if
			break;

		//--Check if menu items are highlighted--
		case WM_MENUSELECT:
			if (HIWORD(wparam) & MF_HILITE)
			{		
				switch (LOWORD(wparam))
				{
					//change
					case ID_OPENCHAOTIXROM:	 strcpy(status, "Opens a Knuckles Chaotix ROM for editing");				break;
					case ID_FILE_EXIT:		 strcpy(status, "Closes the program");										break;
					case MAG_ART:			 strcpy(status, "Zoom in on the current art"); 								break;
					case DEMAG_ART:			 strcpy(status, "Zoom out from the current art");							break;
					case ID_VIEW_GRIDLINES:	 strcpy(status, "Toggles grid-lines used to edit the current art");			break;
					case IDC_SAVE_ART:		 strcpy(status, "Saves current art back into ROM");							break;
					case EXPORT_BITMAP:		 strcpy(status, "Exports current art to a bitmap file");					break;
					case EXPORT_PIXELS:		 strcpy(status, "Exports current art to a file as raw pixel data");			break;
					case IMPORT_BITMAP:		 strcpy(status, "Imports a bitmap file into the current art");				break;
					case IMPORT_PIXELS:		 strcpy(status, "Imports raw pixel data from file into the current art");	break;
					/*case importw/sc:		 strcpy(status, "Closes the program");*/									break;
					case ID_HELP_ABOUT:		 strcpy(status, "Views info about Knuckles Chaotix Art Editor");			break;
					default:																							break;
				}	//end switch

                //Paint dialog
               	RECT frect;
                GetClientRect(hwnd, &frect);
                frect.top = frect.bottom - 21;
                InvalidateRect(hwnd, &frect, false);
			}
			else
			{
				if (strcmp(status, " ") != 0)
				{
					strcpy(status, " ");
                    
       	            //Paint dialog
                   	RECT frect;
                    GetClientRect(hwnd, &frect);
                    frect.top = frect.bottom - 21;
                    InvalidateRect(hwnd, &frect, false); 
				}	//end if
			}	//end if
			break;

		//reset status bar when you exit a menu
		case WM_EXITMENULOOP:
			if (strcmp(status, "Ready") != 0)
			{
				strcpy(status, "Ready");
				
                //Paint dialog
               	RECT frect;
                GetClientRect(hwnd, &frect);
                frect.top = frect.bottom - 21;
                InvalidateRect(hwnd, &frect, false);
			}	//end if
			break;

		//do the default for other stuff
		default:
			return false;
	}	//end switch
	
	return true;
}	//end of func.


void UpdatePointers(pointer them[], HWND hwnd)
{
	//declare variable to hold hex values
	char newhex[10]="";
	
	//Clear all listboxes (get prev selection of first as well)
	int oldsel = SendDlgItemMessage(hwnd, PTR_LST1, LB_GETCURSEL, 0,0);
	SendDlgItemMessage(hwnd, PTR_LST1, LB_RESETCONTENT, 0, 0);
	SendDlgItemMessage(hwnd, PTR_LST2, LB_RESETCONTENT, 0, 0);

	//Update listboxes
	for (int lp=0; lp < sizeof(pdata)/4; lp++)
	{
		sprintf(newhex, "%06X", them[lp].address);
		SendDlgItemMessage(hwnd, PTR_LST1, LB_ADDSTRING, 0, LPARAM(newhex));
	}	//end for

	for (int lp=0; lp < sizeof(them[pl1Sel].pointsto)/4; lp++)
	{
		sprintf(newhex, "%06X", them[pl1Sel].pointsto[lp]);
		SendDlgItemMessage(hwnd, PTR_LST2, LB_ADDSTRING, 0, LPARAM(newhex));
		if (them[pl1Sel].pointsto[lp+1] == 0) { break;}	//leave out unused ptrs.
	}	//end for

	//Selection of first
	SendDlgItemMessage(hwnd, PTR_LST1, LB_SETCURSEL, (WPARAM)oldsel,0);
}	//end of func.


//shorthands
void DrawMainStatusBar(HWND hwnd, HDC hdc)
{
    //Colors to draw with
	HPEN TBLC = CreatePen(0,1,RGB(255,255,255));
	HPEN TTLC = CreatePen(0,1,RGB(167,166,170));
	HPEN TLC = CreatePen(0,1,RGB(220,223,228));
	HPEN BLC = CreatePen(0,1,RGB(234,237,242));
	HBRUSH SBC = CreateSolidBrush(RGB(240,243,248));
	HFONT font = CreateFont(6, 6, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "MS Sans Serif");
	HGDIOBJ oldobj;

    //Get portion to draw status bar
   	RECT frect;
    GetClientRect(hwnd, &frect);
    frect.top = frect.bottom - 21;
	
	//Draw status bar lines
	for (int lp=1; lp <= 4; lp++)
	{
		if (lp == 1) { oldobj=SelectObject(hdc, TTLC); }
		if (lp == 2) { SelectObject(hdc, TBLC); }
		if (lp == 3) { SelectObject(hdc, TLC); }
		if (lp == 4) { SelectObject(hdc, BLC); }

		MoveToEx(hdc, frect.left, frect.top-lp, NULL);
		LineTo(hdc, frect.right, frect.top-lp);
	}	//end for

	//Draw status bar fill
	FillRect(hdc, &frect, SBC);

	//Draw status bar separator
	SelectObject(hdc, TLC);
	MoveToEx(hdc, frect.right - 106, frect.top + 2, NULL);
	LineTo(hdc, frect.right - 106, frect.bottom - 2);
	
	//Draw status bar text
	SelectObject(hdc, font);
	SetBkMode(hdc, TRANSPARENT);
	TextOut(hdc, frect.left+(4), frect.top+(4), status, strlen(status));
	TextOut(hdc, frect.right-100, frect.top+6, status2, strlen(status2));

	//select prev. obj back into dc
	SelectObject(hdc, oldobj);
	
    //Delete stupid stuff
	DeleteObject(TBLC); DeleteObject(TTLC); DeleteObject(TLC); 
	DeleteObject(BLC); DeleteObject(SBC); DeleteObject(font);
}	//end of func.

void PaintColorBoxes(HWND hwnd, HDC hdc)
{
    //Brush to draw
    HBRUSH SBC;
    RECT artBox;             //destination position window coords
    
	for (int palOn=0; palOn<=15; palOn++)
	{	    
	    //Determine relativity to window
        if (GetDlgItemRect(hwnd, (int)((COL_BOX1)+(palOn)), artBox))
        { 
            //Fill rectangle with desired color
       	    SBC = CreateSolidBrush(c32to256(palettes[pl1Sel].colors[palOn]));
    	    FillRect(hdc, &artBox, SBC);
	        DeleteObject(SBC);
        }   //end if
	}	//end for
	
    //Determine relativity to window
    if (GetDlgItemRect(hwnd, COL_SEL, artBox)) 
    {
        //Fill rectangle with desired color
        SBC = CreateSolidBrush(c32to256(palettes[pl1Sel].colors[curCol]));
        FillRect(hdc, &artBox, SBC);
        DeleteObject(SBC);
    }   //end if

}	//end of func.

void BlitBuf(HWND hwnd, HDC hdc, FrameBuffer &buf, int destid)
{
    int W = buf.width;
    int H = buf.height;
    int BitCount = buf.bpp*8;
    
    //Create bitmap info struct for writing pixels
    BITMAPINFO bi; 
    memset(&bi,0,sizeof(BITMAPINFO)); 
    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    bi.bmiHeader.biWidth = W; 
    bi.bmiHeader.biHeight = H; 
    bi.bmiHeader.biPlanes = 1; 
    bi.bmiHeader.biBitCount = BitCount; 
    bi.bmiHeader.biCompression = BI_RGB; 
    bi.bmiHeader.biSizeImage = (bi.bmiHeader.biWidth*bi.bmiHeader.biHeight)*(BitCount/8);  
    
    //destination position window coords
    RECT artBox;
    if (GetDlgItemRect(hwnd, destid, artBox)); 
    {
        //Write pixels
        SetDIBitsToDevice(hdc, 
                    artBox.left+2,artBox.top+2, W,H, 
                    0, 0, 0, bi.bmiHeader.biHeight, 
                    buf.framebuffer,&bi,DIB_RGB_COLORS); 
    }   //end if                   
    
}   //end of func.

bool GetDlgItemRect(HWND hDlg, int id, RECT &rect) 
{
     
    //for functions below
    POINT point = {0,0};
    
    //destination rect
    HWND dest = GetDlgItem(hDlg, id);
    if (!dest) { return false; }
    return GetWindowRect(dest, &rect) && 
           ClientToScreen(hDlg, &point) && 
           OffsetRect(&rect, -point.x, -point.y);
    
}   //end of func.

void InvalidateDlgItem(HWND hDlg, int id)
{
     RECT itemRect;
     if (GetDlgItemRect(hDlg, id, itemRect))
        InvalidateRect(hDlg, &itemRect, false);
}    //end void
